package com.oig.sys.log.service.impl;

import com.alibaba.nacos.shaded.com.google.common.collect.Lists;
import com.oig.common.exception.BadRequestException;
import com.oig.common.module.SysPageInfo;
import com.oig.common.module.SysRequest;
import com.oig.sys.log.dao.ITbSysAuditLogDao;
import com.oig.sys.log.dto.SysAuditLogDto;
import com.oig.sys.log.entity.TbSysAuditLog;
import com.oig.sys.log.service.ITbSysAuditLogService;
import com.oig.sys.log.util.LogQueryUtil;
import com.oig.sys.log.vo.SysAuditLogVo;
import com.oig.sys.security.util.SecurityUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author wuxl
 */
@Service
public class TbSysAuditLogServiceImpl implements ITbSysAuditLogService {

	private final ITbSysAuditLogDao tbSysAuditLogDao;
	private final ElasticsearchRestTemplate elasticsearchTemplate;

	@Autowired
	public TbSysAuditLogServiceImpl(ITbSysAuditLogDao tbSysAuditLogDao,
									ElasticsearchRestTemplate elasticsearchTemplate) {
		this.tbSysAuditLogDao = tbSysAuditLogDao;
		this.elasticsearchTemplate = elasticsearchTemplate;
	}

	@Transactional
	@Override
	public void addSysAuditLog(SysAuditLogDto sysAuditLogDto){
		// 保存审计日志
		TbSysAuditLog auditLog = new TbSysAuditLog();
		BeanUtils.copyProperties(sysAuditLogDto, auditLog);
		if (auditLog.getUserId()==null){
			auditLog.setUserName(SecurityUtil.getUserForIfNullBuild().getUsername());
			auditLog.setUserId(SecurityUtil.getUserForIfNullBuild().getId());
			auditLog.setTenantName(SecurityUtil.getUserForIfNullBuild().getTenantName());
			auditLog.setTenantId(SecurityUtil.getUserForIfNullBuild().getTenantId());
		}
		tbSysAuditLogDao.save(auditLog);
	}


	@Override
	public SysPageInfo<SysAuditLogVo> getSysAuditLogInfo(SysRequest<SysAuditLogDto> request) {
		// 1、生成查询ES日志的实体
		String createStr = "createTime";
		NativeSearchQueryBuilder builder = LogQueryUtil.buildQueryByDto(request, Lists.newArrayList(createStr));
		// 2、添加默认的页面页码和排序   0 代表第一页, 按创建时间倒序
		NativeSearchQuery query = builder.withPageable(PageRequest.of(request.getPageNo() - 1, request.getPageSize()))
				.withSort(Sort.by(new Order(Sort.Direction.DESC, createStr)))
				.build();
		// 3、查询ES
		SearchHits<TbSysAuditLog> search = elasticsearchTemplate.search(query, TbSysAuditLog.class);
		// 4、结果转换Vo
		List<SysAuditLogVo> result = search.getSearchHits().stream().map(item -> {
			TbSysAuditLog content = item.getContent();
			SysAuditLogVo sysAuditLogVo = new SysAuditLogVo();
			BeanUtils.copyProperties(content, sysAuditLogVo);
			return sysAuditLogVo;
		}).collect(Collectors.toList());
		SysPageInfo<SysAuditLogVo> pageInfo = new SysPageInfo<>(request.getPageNo(), request.getPageSize(),
				search.getTotalHits());
		pageInfo.setList(result);
		return pageInfo;
	}

	@Override
	public SysAuditLogVo getSysAuditLogInfoById(String id) {
		Optional<TbSysAuditLog> sysAuditLogOpt = tbSysAuditLogDao.findById(id);
		if (!sysAuditLogOpt.isPresent()) {
			throw new BadRequestException("日志信息未找到");
		}
		SysAuditLogVo sysAuditLogVo = new SysAuditLogVo();
		BeanUtils.copyProperties(sysAuditLogOpt.get(), sysAuditLogVo);
		return sysAuditLogVo;
	}
}
